<template>
  <div @contextmenu.prevent class="elTable">
    <!-- 搜索区域 -->
    <div class="select">
      <el-form ref="form" :model="searchModel" label-width="100px">
        <el-row style="margin-right: 0" :gutter="20">
          <el-col :key="index" v-for="(item, index) in searchList" :span="6">
            <el-form-item :label="item.label">
              <!-- 输入框 -->
              <el-input
                :placeholder="'请输入' + item.label"
                clearable
                v-if="item.type == 'input'"
                v-model="searchModel[[item.prop]]"
              ></el-input>
              <!-- 下拉框 -->
              <el-select
                @change="selectChange(item, searchModel[[item.prop]])"
                clearable
                style="width: 100%"
                v-if="item.type == 'select'"
                v-model="searchModel[[item.prop]]"
                :placeholder="'请选择' + item.label"
              >
                <el-option
                  :key="index"
                  v-for="(dictVal, index) in dict[item.selectDictionary]"
                  :label="dictVal.label"
                  :value="dictVal.code"
                ></el-option>
              </el-select>
              <!-- 时间选择器 -->
              <el-date-picker
                v-if="item.type == 'date'"
                type="date"
                :placeholder="'请选择' + item.label"
                v-model="searchModel[[item.prop]]"
                style="width: 100%"
              ></el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <!-- 搜索重置 -->
      <div class="searchBtn">
        <el-button @click="search" type="primary" icon="el-icon-search"
          >搜索</el-button
        >
        <el-button @click="rest">重置</el-button>
      </div>
    </div>
    <!-- 头部 -->
    <div class="tableTitle">
      <el-button
        @click="handleClick(null, item.methods, item.operateName)"
        :key="item.operateName"
        v-for="item in tableTitleBtn"
        :type="item.btnType"
        >{{ item.operateName }}</el-button
      >
    </div>
    <!-- 表格 -->
    <el-table
      :summary-method="showSummary ? getSummaries : () => {}"
      :show-summary="showSummary"
      @header-click="headerClick"
      @row-dblclick="rowDblClick"
      @cell-mouse-leave="cellMouseLeave"
      @cell-mouse-enter="cellMouseEnter"
      @select-all="selectAll"
      @select="select"
      @sort-change="tableSortChange"
      @row-contextmenu="rightClickChange"
      @current-change="handleCurrentChange"
      :highlight-current-row="isCurrentRowHeight"
      ref="elTable"
      @selection-change="handleSelectionChange"
      :header-cell-style="{ 'text-align': 'center' }"
      :cell-style="{ 'text-align': 'center' }"
      :data="tableDataList"
      border
      style="width: 100%"
    >
      <template v-for="(item, index) in tableLabelList">
        <!-- 序列 -->
        <el-table-column
          :fixed="indexFixed"
          :width="indexWidth"
          :label="item.label"
          v-if="item.type == 'index'"
          :key="index"
        >
          <template slot-scope="scope">{{
            scope.$index + 1 > 9 ? scope.$index + 1 : "0" + (scope.$index + 1)
          }}</template>
        </el-table-column>
        <!-- 复选框选项列 -->
        <el-table-column
          :fixed="selectFixed"
          :width="selectWidth"
          v-else-if="item.type == 'selection'"
          :type="item.type"
        >
        </el-table-column>
        <!-- 操作列 -->
        <el-table-column
          :fixed="operateFixed"
          :width="operateWidth"
          v-else-if="item.type == 'operate'"
          :label="item.label"
        >
          <template slot-scope="scope">
            <span v-for="(operates, index) in item.operate">
              <el-button
                v-if="operates.code != 5"
                :style="{
                  marginRight: index == item.operate.length - 1 ? '0' : '5px',
                }"
                @click.stop="
                  handleClick(scope.row, operates.methods, operates.operateName)
                "
                :type="operates.btnType"
                size="small"
                >{{ operates.operateName }}</el-button
              >
            </span>
          </template>
        </el-table-column>
        <!-- 文件图片列 -->
        <el-table-column :label="item.label" v-else-if="item.type == 'file'">
          <template slot-scope="scope">
            <div class="imageTable">
              <el-badge
                :value="
                  Object.prototype.toString.call(scope.row[item.prop]) ==
                  '[object Array]'
                    ? scope.row[item.prop].length
                    : scope.row[item.prop] == ''
                    ? 0
                    : 1
                "
                class="item imageNum"
              ></el-badge>
              <el-image
                class="imagesBox"
                :preview-src-list="srcList"
                style="width: 100%; height: 60px; cursor: pointer"
                @click.stop="clickImg(scope.row[item.prop])"
                :src="
                  Object.prototype.toString.call(scope.row[item.prop]) ==
                  '[object Array]'
                    ? scope.row[item.prop][0]
                    : scope.row[item.prop]
                "
                fit="cover"
              ></el-image>
            </div>
          </template>
        </el-table-column>
        <!-- 插槽及常规显示列 -->
        <el-table-column
          :show-overflow-tooltip="showOverflowTooltip"
          :width="contentWidth"
          :sortable="item.type === 'custom' ? item.type : false"
          v-else
          :prop="item.prop"
          :label="item.label"
        >
          <template slot-scope="scope">
            <!-- 插槽区 -->
            <template v-if="item.slot">
              <slot :name="item.slot" :scope="scope"></slot>
            </template>
            <!-- 常规显示区 -->
            <template v-else>
              <span>
                {{ scope.row[item.prop] }}
              </span>
            </template>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <!-- 分页 -->
    <div class="pageDv">
      <el-pagination
        @size-change="handlePageSizeChange"
        @current-change="handlePageCurrentChange"
        :current-page="page.currentPage"
        background
        :page-sizes="pageSizes"
        :page-size="page.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="tableDataList.length"
      >
      </el-pagination>
    </div>
    <!-- 弹框菜单 -->
    <div class="bulletBoxClass" ref="bulletBoxRef" v-show="rightClickShow">
      <bulletBox :bulletBoxData="bulletBoxData"></bulletBox>
    </div>
    <!-- dialog -->
    <el-dialog
      @open="dialogOpen"
      @close="dialogClose"
      :title="dialog.title"
      :visible.sync="dialog.visible"
    >
      <!-- 编辑 -->
      <el-form
        :model="editData"
        :rules="rules"
        ref="editForm"
        label-width="100px"
        class="demo-ruleForm"
      >
        <el-row :gutter="20">
          <el-col
            :style="{ marginTop: item.type == 'file' ? '50px' : 0 }"
            :key="index"
            v-for="(item, index) in addList"
            :span="item.type == 'file' ? 24 : 12"
          >
            <el-form-item :prop="item.prop" :label="item.label">
              <!-- 输入框 -->
              <el-input
                :placeholder="'请输入' + item.label"
                :disabled="
                  (dialog.type != 'add' && !item.isEdit) ||
                  dialog.type == 'view'
                "
                clearable
                v-if="item.type == 'input'"
                v-model="editData[[item.prop]]"
              ></el-input>
              <!-- 下拉框 -->
              <el-select
                :disabled="!item.isEdit || dialog.type == 'view'"
                @change="selectChange(item, editData[[item.prop]])"
                clearable
                style="width: 100%"
                v-if="item.type == 'select'"
                v-model="editData[[item.prop]]"
                :placeholder="'请选择' + item.label"
              >
                <el-option
                  :key="index"
                  v-for="(dictVal, index) in dict[item.selectDictionary]"
                  :label="dictVal.label"
                  :value="dictVal.code"
                ></el-option>
              </el-select>
              <!-- 时间选择器 -->
              <el-date-picker
                :disabled="!item.isEdit || dialog.type == 'view'"
                v-if="item.type == 'date'"
                type="date"
                :placeholder="'请选择' + item.label"
                v-model="editData[[item.prop]]"
                style="width: 100%"
              ></el-date-picker>
              <!-- 图片上传区域 -->
              <el-upload
                :limit="uploadLimit"
                :disabled="dialog.type == 'view'"
                list-type="picture-card"
                :on-remove="handleRemove"
                :on-preview="handlePictureCardPreview"
                :file-list="fileList"
                v-if="item.type == 'file'"
                class="avatar-uploader"
                action
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload"
              >
                <i class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <!-- dialog确认取消区域 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialog.visible = false">取 消</el-button>
        <el-button
          v-if="dialog.type != 'view'"
          type="primary"
          @click="dialogConfirm"
          >确 定</el-button
        >
      </span>
    </el-dialog>
    <!-- 图片上传dialog -->
    <el-dialog class="uploadDiaog" :visible.sync="uploadDiaog">
      <img width="100%" :src="imageUrl" alt="" />
    </el-dialog>
  </div>
</template>

<script>
import bulletBox from "@/components/bulletBox";
export default {
  components: {
    bulletBox,
  },
  props: {
    // 字典
    dict: {
      required: false,
      type: Object,
      default: {},
    },
    // 内容的宽度
    contentWidth: {
      required: false,
      type: Number,
      default: NaN,
    },
    // 操作的宽度
    operateWidth: {
      required: false,
      type: Number,
      default: NaN,
    },
    // 序列号的宽度
    indexWidth: {
      required: false,
      type: Number,
      default: 100,
    },
    // 勾选栏的宽度
    selectWidth: {
      required: false,
      type: Number,
      default: 60,
    },
    // 操作栏固定的位置
    operateFixed: {
      required: false,
      type: String,
      default: "right",
    },
    // 序列号固定的位置
    indexFixed: {
      required: false,
      type: String,
      default: "left",
    },
    // 勾选栏固定的位置
    selectFixed: {
      required: false,
      type: String,
      default: "left",
    },
    // 表格表头数据
    tableLabelList: {
      required: true,
      type: Array,
    },
    // 表格内容数据
    tableDataList: {
      required: true,
      type: Array,
    },
    //点击当前行是否高亮
    isCurrentRowHeight: {
      required: false,
      type: Boolean,
      default: false,
    },
    // 是否可以被右键单击
    isRightClick: {
      required: false,
      type: Boolean,
      default: false,
    },
    // 内容隐藏是否显示tooltip
    showOverflowTooltip: {
      required: false,
      type: Boolean,
      default: false,
    },
    // 请求的参数
    requestData: {
      required: true,
      type: Object,
      default: {},
    },
    // 表单验证规则
    rules: {
      required: false,
      type: Object,
      default: {},
    },
    // 上传最大数
    uploadLimit: {
      required: false,
      type: Number,
      default: 3,
    },
    // 分页每页多式条
    pageSizes: {
      required: false,
      type: Array,
      default: () => [10, 20, 30, 50, 100],
    },
    // 分页当前页当前多少条
    page: {
      required: false,
      type: Object,
      default: () => {
        return {
          currentPage: 1, //当前页
          pageSize: 10, //每页显示条数
        };
      },
    },
    // 是否需要合计列
    showSummary: {
      required: false,
      type: Boolean,
      default: false,
    },
  },
  computed: {
    tableTitleBtn() {
      var btns = [];
      this.tableLabelList.forEach((item) => {
        if (item.type === "operate") {
          let t = item.operate;
          t.forEach((item) => {
            if (item.code != 1 && item.code != 2) {
              btns.push(item);
            }
          });
        }
      });
      return btns;
    },
  },
  watch: {
    rules: {
      handler(value) {
        this.rules = value;
      },
      immediate: true,
    },
    tableLabelList: {
      handler(value) {
        let selectsModel = [];
        this.searchList = [];
        // this.searchModel
        value.forEach((item, index) => {
          if (item.isSeach == 1) {
            selectsModel.push(item.prop);
            this.searchList.push(item);
          }
          if (item.isAdd == 1) {
            this.addList.push(item);
          }
        });
        // value.forEach(item => {
        //   if (item.isAdd == 1) {
        //     this.$set(this.addData, item.prop, '')
        //   }
        // })
        selectsModel.forEach((item) => {
          this.$set(this.searchModel, item, "");
        });
        // console.log(this.searchList, ' this.searchList this.searchList')
      },
      // deep: true,
      immediate: true,
    },
  },
  data() {
    return {
      rightClickShow: false, //右键点击显示
      bulletBoxData: {}, //右键table列菜单弹框数据
      searchModel: {}, //可以被搜索的对象字段
      searchList: [], //可以被搜索的数组
      dialog: {
        //dialog弹框相关参数
        visible: false,
        title: "",
        operate: "",
        type: "",
      },
      addList: [], //可以被新增的项
      selectList: [], //表格选中项
      editData: {}, //要编辑查看新增的数据
      srcList: [], //多图片
      fileList: [], //上传的文件
      imageUrl: "", //图片上传预览
      uploadDiaog: false, //查看图片预览diaog
    };
  },
  created() {
    this.search();
  },
  mounted() {
    window.addEventListener("click", this.closeBulletBox);
  },
  methods: {
    // 自定义计算合计
    getSummaries(param) {
      const { columns, data } = param;
      // console.log(columns,'sss')
      const sums = [];
      let sumTable = this.tableLabelList.filter((item) => {
        if (item.isSum) {
          return item;
        }
      });
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = "合计";
          return;
        }
        let sumColumn = [];
        // console.log(sumTable, 'sumTable')
        let unit = "";
        sumTable.forEach((itemSum) => {
          // console.log(column,'column')
          if (itemSum.label == column.label) {
            sumColumn.push(column.property);
            unit = itemSum.unit;
          }
        });
        // console.log(sumColumn,'sumColumnsumColumn')
        // console.log(sumTable, 'sumTablesumTablesumTable')
        let values = [];
        data.forEach((item) => {
          // console.log(item, 'itemitemitem')
          sumColumn.forEach((sumColumnItem, index) => {
            // return Number(item[sumColumnItem])
            values.push(Number(item[sumColumnItem]));
          });
        });
        // console.log(values,'vvvv')
        if (!values.every((value) => isNaN(value))) {
          sums[index] = values.reduce((prev, curr) => {
            const value = Number(curr);
            if (!isNaN(value)) {
              return prev + curr;
            } else {
              return prev;
            }
          }, 0);
          sums[index] += unit;
        } else {
          sums[index] = "/";
        }
      });

      return sums;
    },
    // table列图片
    clickImg(value) {
      this.srcList = [];
      Object.prototype.toString.call(value) == "[object Array]"
        ? (this.srcList = value)
        : this.srcList.push(value);
    },
    // 下拉框选择
    selectChange(item, value) {
      this.$emit("getSelectChange", item, value);
    },
    // 搜索
    search() {
      this.searchModel.page = this.page;
      console.log(this.searchModel, "search");
      this.sendAjax(
        this.requestData.search.url,
        this.searchModel,
        this.requestData.search.method,
        "getSearch"
      );
    },
    // 重置
    rest() {
      this.searchList.forEach((item, index) => {
        this.searchModel[item.prop] = "";
      });
      this.$emit("getRest", this.searchModel);
    },
    //勾选单个
    select(selection, row) {
      this.$emit("select", selection, row);
    },
    // 勾选全选
    selectAll(selection) {
      this.$emit("selectAll", selection);
    },
    // 关闭弹出框
    closeBulletBox() {
      this.rightClickShow = false;
    },
    // select选择框
    handleSelectionChange(value) {
      this.selectList = value;
      this.$emit("selectionChange", value);
    },
    // 取消table选中的状态
    toggleRowSelection() {
      this.selectList.forEach((item) => {
        this.$refs.elTable.toggleRowSelection(item, false);
      });
    },
    // 当前行被点击
    handleCurrentChange(value) {
      this.$emit("clickCurrentChange", value);
    },
    // 当前行被右键点击
    rightClickChange(row, column, event) {
      if (this.isRightClick) {
        this.rightClickShow = true;
        this.bulletBoxData = row;
        console.log(event, "====");
        this.$refs.bulletBoxRef.style.left = event.pageX + "px";
        this.$refs.bulletBoxRef.style.top = event.pageY - 50 + "px";
        this.$emit("rightClick", row, column, event);
      }
    },
    // 排序
    tableSortChange(value) {
      this.$emit("sortChange", value);
    },
    // 当单元格 hover 进入时会触发该事件
    cellMouseEnter(row, column, cell, event) {
      this.$emit("cellMouseEnter", row, column, cell, event);
    },
    // 当单元格 hover 退出时会触发该事件
    cellMouseLeave(row, column, cell, event) {
      this.$emit("cellMouseLeave", row, column, cell, event);
    },
    // 当某一行被双击时会触发该事件
    rowDblClick(row, column, event) {
      this.$emit("rowDblClick", row, column, event);
    },
    // 当某一列的表头被点击时会触发该事件
    headerClick(column, event) {
      this.$emit("headerClick", column, event);
    },
    // 切换当前页
    handlePageCurrentChange(val) {
      this.page.currentPage = val;
      this.search();
    },
    // 切换显示条数
    handlePageSizeChange(val) {
      this.page.pageSize = val;
      this.search();
    },
    // =========================================================
    // =========================================================
    // =========================================================
    handleClick(row, methods, type) {
      this.$options.methods[methods](row, this, type);
      this.dialog.title = type;
      this.dialog.type = methods;
      this.dialog.visible = methods !== "delete" && methods !== "export";
    },
    // 图片上传on-success
    handleAvatarSuccess() {},
    // 图片上传before-upload
    beforeAvatarUpload(file) {
      const isJPG = file.type === "image/jpeg" || file.type === "image/png";
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error("上传头像图片只能是 JPG、PNG 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      console.log(document.getElementsByClassName("el-upload"));
      return isJPG && isLt2M;
    },
    // 图片上传on-remove
    handleRemove() {},
    // 图片上传on-preview
    handlePictureCardPreview(file) {
      console.log(file);
      this.imageUrl = file.url;
      this.uploadDiaog = true;
    },
    // 发送网络请求
    sendAjax(url, data, method, emitMethodStr) {
      // return new Promise((resolve, reject) => {
      // this.$http({
      //   url,
      //   data,
      //   method,
      // }).then((res) => {
      //   this.search()
      //   this.$emit(emitMethodStr,res)
      // resolve()
      // }).catch((err) => {
      //   this.search()
      //   this.$emit(emitMethodStr,err)
      // reject()
      // });
      // })
    },
    // dialog关闭
    dialogClose() {
      this.addList.forEach((item) => {
        this.editData[item.prop] = "";
      });
      this.fileList = [];
      this.$refs["editForm"].resetFields();
      this.$emit("getDialogClose", this.editData);
    },
    // dialog打开
    dialogOpen() {
      this.$nextTick(() => {
        // this.$refs['editForm'].resetFields();
      });
    },
    // dialog确认按钮
    dialogConfirm() {
      this.$refs["editForm"].validate((valid) => {
        if (valid) {
          switch (this.dialog.operate) {
            case "add":
              this.tableLabelList.forEach((item) => {
                if (item.isAdd == 1) {
                  if (!this.editData[item.prop]) {
                    this.editData[item.prop] = "";
                  }
                }
              });
              // console.log(this.editData,'ddddd')
              this.sendAjax(
                this.requestData.add.url,
                this.editData,
                this.requestData.add.method,
                "addConfirm"
              );
              break;
            case "view":
              this.sendAjax(
                this.requestData.view.url,
                this.editData,
                this.requestData.view.method,
                "viewConfirm"
              );
              break;
            case "edit":
              this.sendAjax(
                this.requestData.edit.url,
                this.editData,
                this.requestData.edit.method,
                "editConfirm"
              );
              break;
          }

          this.dialog.visible = false;
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    // 图片上传回显处理
    getFileList(row, vm) {
      vm.tableLabelList.forEach((item, index) => {
        if (item.type == "file") {
          if (
            Object.prototype.toString.call(row[item.prop]) ==
              "[object Array]" &&
            row[item.prop].length
          ) {
            row[item.prop].forEach((value) => {
              let obj = {
                name: value,
                url: value,
              };
              vm.fileList.push(obj);
            });
          } else {
            if (row[item.prop].length) {
              let obj = {
                name: row[item.prop],
                url: row[item.prop],
              };
              vm.fileList.push(obj);
            }
          }
        }
      });
    },
    // 新增
    add(row, vm, type) {
      vm.dialog.operate = "add";
      vm.editData = {};
      vm.$emit("getAdd", type);
    },
    // 查看
    view(row, vm, type) {
      vm.dialog.operate = "view";
      vm.editData = JSON.parse(JSON.stringify(row));
      this.getFileList(row, vm);
      vm.$emit("getDetails", row, type);
    },
    // 编辑

    edit(row, vm, type) {
      vm.dialog.operate = "edit";
      vm.editData = JSON.parse(JSON.stringify(row));
      this.getFileList(row, vm);
      vm.$emit("getEdit", row, type);
    },
    // 确认事件
    confirmChange(data, type, url, method, emitMethodStr) {
      return new Promise((resolve, reject) => {
        this.$confirm(`确认${type}, 是否继续?`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            this.$message({
              type: "success",
              message: `${type}成功!`,
            });
            this.sendAjax(url, data, method, emitMethodStr).then((res) => {
              resolve();
            });
          })
          .catch(() => {
            this.$message({
              type: "info",
              message: `取消${type}`,
            });
            reject();
          });
      });
    },
    // 导出
    export(row, vm, type) {
      if (row) {
        vm.confirmChange(
          row,
          "导出",
          vm.requestData.export.url,
          vm.requestData.export.method,
          "getExport"
        );
      } else {
        let sendData = vm.selectList.map((item) => {
          return item.id;
        });
        if (sendData.length) {
          vm.confirmChange(
            sendData,
            "导出",
            vm.requestData.export.url,
            vm.requestData.export.method,
            "getExport"
          ).catch((err) => {
            vm.toggleRowSelection();
            vm.selectList = [];
          });
        } else {
          vm.$message({
            type: "info",
            message: `请选择!`,
          });
        }
      }
    },
    // 删除
    delete(row, vm, type) {
      if (row) {
        vm.confirmChange(
          row,
          "删除",
          vm.requestData.del.url,
          vm.requestData.del.method,
          "getDelete"
        );
      } else {
        let sendData = vm.selectList.map((item) => {
          return item.id;
        });
        if (sendData.length) {
          vm.confirmChange(
            sendData,
            "删除",
            vm.requestData.del.url,
            vm.requestData.del.method,
            "getDelete"
          ).catch((err) => {
            vm.toggleRowSelection();
            vm.selectList = [];
          });
        } else {
          vm.$message({
            type: "info",
            message: "请选择!",
          });
        }
      }
    },
  },
};
</script>

<style>
.elTable {
  position: relative;
}

.bulletBoxClass {
  width: 200px;
  position: absolute;
}

.tableTitle {
  display: flex;
  justify-content: right;
  align-content: center;
  background-color: #ccc;
  padding: 30px 10px;
}

.select {
  margin-bottom: 60px;
  position: relative;
}

.searchBtn {
  position: absolute;
  right: 30px;
  bottom: -30px;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

/* 禁用小手样式 */
.cursorNoDrop {
  cursor: no-drop !important;
}

.avatar-uploader {
  /* padding-right: 99px; */
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  text-align: center;
}

.avatar {
  display: block;
}

.imageTable {
  position: relative;
  height: 60px;
}

.imageNum {
  position: absolute;
  right: -8px;
  top: 0;
  z-index: 99;
}

.imagesBox {
  position: absolute;
  left: 0;
  top: 0;
}

.uploadDiaog .el-dialog__body {
  padding: 0;
  height: 0;
}

.uploadDiaog .el-dialog__header {
  padding: 0;
}

.uploadDiaog button {
  display: none;
}

.el-upload--picture-card {
}

.pageDv {
  margin: 50px 50px 50px 0;
  display: flex;
  justify-content: flex-end;
}

.el-pager li {
  /* background-color: rgb(100, 98, 98) !important; */
}

.cell {
  text-align: center !important;
}
</style>
